
#ifndef _TTG_SERVICES_TASKSCHEDULER_TASKSCHEDULER_
#define _TTG_SERVICES_TASKSCHEDULER_TASKSCHEDULER_
#include "Common/Definitions.h"

#include "Runtime.Low/Threads.h"
#include "Runtime.Low/Services/Service.h"

#include "TaskSchedulerSettings.h"
#include "ITaskScheduler.h"
#include "SchedulingAlgorithm.h"
#include "DeviceState.h"

namespace ttg
{
	namespace services
	{
		//Service, that manages and provides correct thread pool.
		class TaskScheduler :public Service,
							 public ITaskScheduler<threads::Task *>,
							 public ITaskScheduler<WiseTask *>
		{
			private:
				static TaskScheduler *ref;
			private:
				TaskSchedulerSettings settings;
				ttg::utils::ParameterSet *filter;
				threads::ThreadPool *pool;
				std::vector<ttg_internal::services::DeviceState *> device_states;
				ttg_internal::services::SchedulingAlgorithm *algorithm;
				threads::FastCriticalSection locker;
				bool is_idle;
				//Creates unstarted task scheduler.
				TaskScheduler();
				//Handler for ThreadPool::onIdle event.
				static ttg::threads::Task *onIdlePerformer(TaskScheduler *scheduler,
														   size_t idle_performers);
				//Sends required tasks to pool [thread-unsafe].
				void sendTasks(size_t task_count);
			protected:
				//Service member.
				virtual void startUnSafe(std::vector<Service *> &deps, const char *params);
				//Service member.
				virtual void stopUnSafe();
			public:
				//ITaskScheduler<Task *> member.
				virtual void split(std::vector<ttg::threads::Task *> &tasks,
								   std::vector<ttg::threads::Task *> &root_tasks,
								   std::vector<ttg::threads::Task *> &child_tasks);
				//ITaskScheduler<WiseTask *> member.
				virtual void split(std::vector<WiseTask *> &tasks,
								   std::vector<WiseTask *> &root_tasks,
								   std::vector<WiseTask *> &child_tasks)
				{ algorithm->split(tasks, root_tasks, child_tasks); }
				//ITaskScheduler<Task *> member. Adds set of tasks.
				virtual void addTasks(ttg::structures::Enumerator<ttg::threads::Task *> &en);
				//ITaskScheduler<WiseTask *> member. Adds set of tasks.
				virtual void addTasks(ttg::structures::Enumerator<WiseTask *> &en);
				virtual ~TaskScheduler();
				//Returns reference to instance (which is always exists).
				static TaskScheduler *getRef()
				{ return ref == NULL ? (ref = new TaskScheduler()) : ref; }
		};
	}
}

#endif
